package cn.gzjp.common.redpack;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;


public class WxRedBagSender {
	
	
	/**
	 * 
	 * @param openid  用户openid
 	 * @param totalAmount 金额(分)
	 * @param sendName 发送名称(公众号名称)
	 * @param nickName 收红包者昵称
	 * @param wishing  祝福语
	 * 
	 * @throws Exception
	 */
	
	/**
	* @param openid  用户openid
 	 * @param totalAmount 金额(分)
	 * @param sendName 发送名称(公众号名称)
	 * @param nickName 收红包者昵称
	 * @param wishing  祝福语
	 * @param mchId 商户号
	 * @param appId appId
	 * @throws Exception
	 */
	public static boolean send(String openid,String totalAmount,String sendName,String nickName,String wishing,String mchId,String appId,String mpAccount) throws Exception {
		// 获取uuid作为随机字符串
		String nonceStr = UUIDUitl.getInstance().generate();
		String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
		String code = MD5.createCode(10);
		RedPackPo sendRedPackPo = new RedPackPo();

		sendRedPackPo.setNonce_str(nonceStr);
		sendRedPackPo.setMch_billno(mchId + today + code);
		sendRedPackPo.setMch_id(mchId);
		sendRedPackPo.setWxappid(appId);
		sendRedPackPo.setNick_name(nickName);
		sendRedPackPo.setSend_name(sendName);
		sendRedPackPo.setRe_openid(openid);
		sendRedPackPo.setTotal_amount(totalAmount);
		sendRedPackPo.setMin_value(totalAmount);
		sendRedPackPo.setMax_value(totalAmount);
		sendRedPackPo.setTotal_num("1");
		sendRedPackPo.setWishing(wishing);
		sendRedPackPo.setClient_ip("192.168.1.1"); // IP
		sendRedPackPo.setAct_name("用户提现");
		sendRedPackPo.setRemark("用户提现！");
		
		String nName = "123456789";
		if(!sendRedPackPo.getNick_name().equals("")){
			nName=sendRedPackPo.getNick_name();
		}
		
		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("nonce_str", sendRedPackPo.getNonce_str());
		sParaTemp.put("mch_billno", sendRedPackPo.getMch_billno());
		sParaTemp.put("mch_id", sendRedPackPo.getMch_id());
		sParaTemp.put("wxappid", sendRedPackPo.getWxappid());
		sParaTemp.put("nick_name",nName );
		sParaTemp.put("send_name", sendRedPackPo.getSend_name());
		sParaTemp.put("re_openid", sendRedPackPo.getRe_openid());
		sParaTemp.put("total_amount", sendRedPackPo.getTotal_amount());
		sParaTemp.put("min_value", sendRedPackPo.getMin_value());
		sParaTemp.put("max_value", sendRedPackPo.getMax_value());
		sParaTemp.put("total_num", sendRedPackPo.getTotal_num());
		sParaTemp.put("wishing", sendRedPackPo.getWishing());
		sParaTemp.put("client_ip", sendRedPackPo.getClient_ip());
		sParaTemp.put("act_name", sendRedPackPo.getAct_name());
		sParaTemp.put("remark", sendRedPackPo.getRemark());
		

		// 除去数组中的空值和签名参数
		Map<String, String> sPara = MD5.paraFilter(sParaTemp);
		String prestr = MD5.createLinkString(sPara); // 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
		String key = "&key=Dm93smT43iM92389M1Qjc8ew4v281yMw"; // 商户支付密钥
		String mysign = MD5.sign(prestr, key, "utf-8").toUpperCase();

		sendRedPackPo.setNick_name(nName);
		sendRedPackPo.setSign(mysign);

		String respXml = MessageUtil.messageToXml(sendRedPackPo);
		System.out.println(respXml);

		// 打印respXml发现，得到的xml中有“__”不对，应该替换成“_”
		respXml = respXml.replace("__", "_");

		// 将解析结果存储在HashMap中
		Map<String, String> map = new HashMap<String, String>();

		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		FileInputStream instream  = new FileInputStream(new File("/home/webapp_2018/car/apiclient_cert.p12")); // 此处为证书所放的绝对路径

		//FileInputStream instream = new FileInputStream(new File("E:\\aisihair\\apiclient_cert.p12")); // 此处为证书所放的绝对路径
		try {
			keyStore.load(instream, mchId.toCharArray());
		} finally {
			instream.close();
		}

		// Trust own CA and all self-signed certs
		SSLContext sslcontext = SSLContexts.custom()
				.loadKeyMaterial(keyStore, mchId.toCharArray()).build();
		// Allow TLSv1 protocol only
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
				sslcontext, new String[] { "TLSv1" }, null,
				SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		CloseableHttpClient httpclient = HttpClients.custom()
				.setSSLSocketFactory(sslsf).build();

		try {

			HttpPost httpPost = new HttpPost(
					"https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack");

			StringEntity reqEntity = new StringEntity(respXml, "utf-8");

			// 设置类型
			reqEntity.setContentType("application/x-www-form-urlencoded");

			httpPost.setEntity(reqEntity);

			System.out.println("executing request" + httpPost.getRequestLine());

			CloseableHttpResponse response = httpclient.execute(httpPost);
			try {
				HttpEntity entity = response.getEntity();
				System.out.println(response.getStatusLine());
				if (entity != null) {

					// 从request中取得输入流
					InputStream inputStream = entity.getContent();
					// 读取输入流
					SAXReader reader = new SAXReader();
					Document document = reader.read(inputStream);
					// 得到xml根元素
					Element root = document.getRootElement();
					// 得到根元素的所有子节点
					List<Element> elementList = root.elements();

					// 遍历所有子节点
					for (Element e : elementList)
						map.put(e.getName(), e.getText());

					// 释放资源
					inputStream.close();
					inputStream = null;

				}
				EntityUtils.consume(entity);
			} finally {
				response.close();
			}
		} finally {
			httpclient.close();
		}

		// 返回状态码
		String return_code = map.get("return_code");
		// 返回信息
		String return_msg = map.get("return_msg");
		// 业务结果
		String result_code = map.get("result_code");
		// 错误代码
		String err_code = map.get("err_code");
		// 错误代码描述
		String err_code_des = map.get("err_code_des");
		System.out.println("return_code="+return_code);
		System.out.println("return_msg="+return_msg);
		System.out.println("result_code="+result_code);
		System.out.println("err_code="+err_code);
		System.out.println("err_code_des="+err_code_des);
		if(return_code.equals("SUCCESS")){
			return true;
		}
		return false;

	}
	
	
	
	public static void main(String[] args) {
		try {
			WxRedBagSender.send("o8zdGt5rjJxVXkAEGsCWf9xsxto0", 1*100+"", "艾丝假发", "高威威", "感谢您购买艾丝假发官方正品","1241630202","wxe16bdbddc3e380a5",null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
